﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
//using Ribbon.OrganizationService;
using System.Windows.Threading;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk;
using System.Collections.Generic;

namespace VisualRibbonEditor
{
 

	public static class MetadataCache
	{
	
		private static System.Collections.Generic.Dictionary<string, EntityMetadata> _cache = 
			new System.Collections.Generic.Dictionary<string, EntityMetadata>();

		private static bool _allEntitiesRetrieved = false;
		public static bool AllEntitiesRetrieved
		{
			get { return _allEntitiesRetrieved; }
			set { _allEntitiesRetrieved = value; }
		}

		public static void GetEntityMetadata(string entityName, Action<EntityMetadata> callback )
		{
			if( _cache.ContainsKey(entityName))
			{
				callback(_cache[entityName]);
			}
			else
			{
				 
				OrgRequest request = new OrgRequest("RetrieveEntity");
				request.Parameters.Add("LogicalName", entityName);
				request.Parameters.Add("EntityFilters", EntityFilters.Entity);
				request.Parameters.Add("RetrieveAsIfPublished", true);
				request.Parameters.Add("MetadataId", new Guid("00000000-0000-0000-0000-000000000000"));
				
				var svc = Helpers.GetOrgService();
				svc.ExecuteAsync(request.ToOrganizationRequest(), (response) =>
					{
						EntityMetadata data = (EntityMetadata) response.Results["EntityMetadata"];
						_cache[entityName] = data;
						callback(data);
					});
			} 
		}


		public static void GetAllEntityNames(Action<EntityMetadata[]> callback)
		{
			if (_allEntitiesRetrieved)
			{
				callback(_cache.Values.ToArray());
			}
			else
			{
				Dispatcher d = Dispatcher.CurrentDispatcher;
				BackgroundWorker b = new BackgroundWorker();
				b.DoWork += (sender, e) =>
					{
						OrgRequest request = new OrgRequest("RetrieveAllEntities");
						request.Parameters.Add("EntityFilters", EntityFilters.Entity);
						request.Parameters.Add("RetrieveAsIfPublished", true);

						var svc = Helpers.GetOrgService();
						svc.ExecuteAsync(request.ToOrganizationRequest(), (response) =>
							{
								EntityMetadata[] data = (EntityMetadata[]) response.Results["EntityMetadata"];
								foreach (EntityMetadata emd in data)
								{
									_cache[emd.LogicalName] = emd;
								}
								_allEntitiesRetrieved = true;

								object[] parms = new object[] {data};
								d.Invoke(callback, parms);
							});
					};
				b.RunWorkerAsync();
			}
		}






	}
}
